/*
 * main.c
 *
 *  Created on: Apr 12, 2011
 *      Author: Grupo ?
 */

#include <getopt.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <openssl/evp.h>
#include "lib/params.h"
#include "lib/wav.h"



int
main(int argc, char * argv[])
{
	Params params;
	EVP_CIPHER_CTX ctx;
	const EVP_CIPHER *cypher;
	int inl, outl, templ;

	unsigned char * out;

	initParams(&params);
	//PARA PROBAR HAY 2 MANERAS, UNA ES SETEAR EL ARGV, LA OTRA EN EL RUNN CONF HAY UNA OPCION, USEN ESO.
	if (getParams(argc, argv, &params) == 0)
	{
		return 1;
	}



	switch(params.a){
		case AES128:
			switch(params.m){
				case ECB:
					cypher = EVP_aes_128_ecb();
					break;
				case CBC:
					cypher=EVP_aes_128_cbc();
					break;
				case OFB:
					cypher=EVP_aes_128_ofb();
					break;
				case CFB:
					cypher=EVP_aes_128_cfb8();
					break;
				default:
					fprintf(stderr, "Modo invalido");
					return 1;
			}
			break;
		case AES192:
			switch(params.m){
				case ECB:
					cypher=EVP_aes_192_ecb();
					break;
				case CBC:
					cypher=EVP_aes_192_cbc();
					break;
				case OFB:
					cypher=EVP_aes_192_ofb();
					break;
				case CFB:
					cypher=EVP_aes_192_cfb8();
					break;
				default:
					fprintf(stderr, "Modo invalido");
					return 1;
			}
			break;
		case AES256:
			switch(params.m){
				case ECB:
					cypher=EVP_aes_256_ecb();
					break;
				case CBC:
					cypher=EVP_aes_256_cbc();
					break;
				case OFB:
					cypher=EVP_aes_256_ofb();
					break;
				case CFB:
					cypher=EVP_aes_256_cfb8();
					break;
				default:
					fprintf(stderr, "Modo invalido");
					return 1;
			}
			break;
		case DES:
			switch(params.m)
			{
				case ECB:
					cypher=EVP_des_ecb();
					break;
				case CBC:
					cypher=EVP_des_cbc();
					break;
				case OFB:
					cypher=EVP_des_ofb();
					break;
				case CFB:
					cypher=EVP_des_cfb8();
					break;
				default:
					fprintf(stderr, "Modo invalido");
					return 1;
			}
			break;
		default:
			fprintf(stderr,"Cipher invalido");
			return 1;
	}

	inl=strlen(params.in);

	wavT * wav = loadWavFile(params.in);

	if (wav == NULL)
	{
		fprintf(stderr, "Error, wav file invalido o inexistente\n");
		return 1;
	}

	out = calloc(1, wav -> data.chunkSize + 1024); // extra space

	if (params.pass[0] != '\0')
	{
		EVP_BytesToKey(cypher, EVP_md5(),NULL, (unsigned char *)params.pass, strlen(params.pass), 1, (unsigned char *)params.key, (unsigned char *)params.iv);
	}

	EVP_CIPHER_CTX_init(&ctx);
	EVP_CIPHER_CTX_set_padding(&ctx, 0); // NO PADDING!

	EVP_CipherInit_ex(&ctx, cypher, NULL, (unsigned char *)params.key, (unsigned char *)params.iv, params.op);
	EVP_CipherUpdate(&ctx, out, &outl, wav -> data.soundData, wav -> data.chunkSize);
	EVP_CipherFinal_ex(&ctx, out + outl, &templ);
	EVP_CIPHER_CTX_cleanup(&ctx);


	free(wav -> data.soundData);
	wav -> data.soundData = out;
	wav -> data.chunkSize = outl;
	saveWavFile(params.out, wav);
	free(wav -> data.soundData);
	free(wav);
	//HAY QUE USAR ESTA FUNC PARA QUE SEA TODO CON LA MISMA FUNCION. HAY QUE HACER UN PAR DE SWITCHS PARA VER
	//QUE PARAMETROS LE TENEMOS QUE PASAR.
	//EVP_CipherInit_ex(&ctx, )

	return 0;
}

